package com.youi.third.yibaopay;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yeepay.g3.sdk.yop.client.YopRequest;
import com.yeepay.g3.sdk.yop.client.YopResponse;
import com.yeepay.g3.sdk.yop.client.YopRsaClient;
import com.yeepay.g3.sdk.yop.encrypt.DigitalEnvelopeDTO;
import com.yeepay.g3.sdk.yop.utils.DigitalEnvelopeUtils;
import com.youi.common.Common;
import com.youi.entity.Userorder;
import com.youi.entity.Userwechat;
import com.youi.entity.Yibaodivide;
import com.youi.entity.Yibaopayment;
import com.youi.model.Branchbank;
import com.youi.third.wechat.util.WechatUtil;
import com.youi.third.yibaopay.model.CashierdeskResult;
import com.youi.third.yibaopay.model.Divideresult;
import com.youi.third.yibaopay.model.Refundresult;
import com.youi.third.yibaopay.model.YibaoorderResult;
import com.youi.util.JsonUtil;
import com.youi.util.SmsUtil;
import sun.misc.BASE64Decoder;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
 * 易宝支付工具类
 *
 * @author Administrator
 */
public class YibaopayUtil {

    public static String PRIVATEKEY = null;//平台商密钥
    public static String ParentMerchantNo = null;//系统商编
    public static String MerchantNo = null;//子商户编号
    public static String NotifyUrl = null;//支付成功服务器回调地址
    public static String RefundNotifyUrl = null;//退款成功服务器回调地址
    public static String PUBLICKEY = null;//平台商公钥

    /**
     * 加载配置文件
     */
    static {
        Properties prop = new Properties();
        InputStream in = YibaopayUtil.class.getResourceAsStream("/yibaopay.properties");
        try {
            prop.load(in);
            String prfix = "yibaopay.";//前缀
            PRIVATEKEY = prop.getProperty(prfix + "PRIVATEKEY").trim();
            ParentMerchantNo = prop.getProperty(prfix + "ParentMerchantNo").trim();
            MerchantNo = prop.getProperty(prfix + "MerchantNo").trim();
            NotifyUrl = prop.getProperty(prfix + "NotifyUrl");
            RefundNotifyUrl = prop.getProperty(prfix + "RefundNotifyUrl".trim());
            PUBLICKEY = prop.getProperty(prfix + "PUBLICKEY".trim());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public YibaopayUtil(String privateKey, String parentMerchantNo, String merchantNo, String notifyUrl) {
        YibaopayUtil.PRIVATEKEY = privateKey;
        YibaopayUtil.ParentMerchantNo = parentMerchantNo;
        YibaopayUtil.MerchantNo = merchantNo;
        YibaopayUtil.NotifyUrl = notifyUrl;
    }

    /**
     * 创建订单返回token
     *
     * @param userorder  订单信息
     * @param ordergoods 订单商品信息
     * @return
     * @throws IOException
     */
    public static YibaoorderResult createOrder(String serialNumber, Double amount) throws IOException {
        Map<String, String> parms = new HashMap<>();
        YopRequest request = new YopRequest("OPR:" + ParentMerchantNo, PRIVATEKEY);
        parms.put("parentMerchantNo", ParentMerchantNo);
        parms.put("merchantNo", MerchantNo);
        //订单号
        parms.put("orderId", serialNumber);
        //订单金额(单位:元)
        DecimalFormat orderAmount = new DecimalFormat("0.00");
        parms.put("orderAmount", orderAmount.format(amount));
        //服务器通知地址
        parms.put("notifyUrl", NotifyUrl);

        request.addParam("parentMerchantNo", ParentMerchantNo);
        request.addParam("merchantNo", MerchantNo);
        request.addParam("orderId", serialNumber);
        request.addParam("orderAmount", orderAmount.format(amount));
        request.addParam("notifyUrl", NotifyUrl);
        request.addParam("goodsParamExt", "{\"goodsName\":\"美宜佳健康商城商品\",\"goodsDes\":\"美宜佳健康商城商品\"}");
        request.addParam("fundProcessType", "DELAY_SETTLE");
        //签名
        request.addParam("hmac", HmacUtil.gethamc(parms));
        // 发送请求
        YopResponse response = YopRsaClient.post("/rest/v1.0/sys/trade/order", request);
        //解析返回
        YibaoorderResult createorderResult = null;
        if ("FAILURE".equals(response.getState())) {
            if (response.getError() != null)
                createorderResult.setCode(response.getError().getCode());
            createorderResult.setMessage(response.getError().getMessage());
        }
        if (response.getStringResult() != null) {
            String jsonString = JsonUtil.toJson(response.getResult());
            createorderResult = JsonUtil.fromJson(jsonString, YibaoorderResult.class);
        }
        return createorderResult;
    }

    /**
     * 查询易宝订单
     *
     * @param orderNo
     * @param uniqueOrderNo
     * @throws IOException
     */
    public static JSONObject getYibaoorder(String orderNo, String uniqueOrderNo) throws IOException {
        //签名参数
        Map<String, String> parms = new HashMap<>();
        parms.put("parentMerchantNo", ParentMerchantNo);
        parms.put("merchantNo", MerchantNo);
        parms.put("orderId", orderNo);
        parms.put("uniqueOrderNo", uniqueOrderNo);
        //请求连接
        YopRequest request = new YopRequest("OPR:" + ParentMerchantNo, PRIVATEKEY);
        request.addParam("parentMerchantNo", ParentMerchantNo);
        request.addParam("merchantNo", MerchantNo);
        request.addParam("orderId", orderNo);
        request.addParam("uniqueOrderNo", uniqueOrderNo);
        request.addParam("hmac", HmacUtil.getYibaoOrderhamc(parms));
        YopResponse response = YopRsaClient.post("/rest/v1.0/sys/trade/orderquery", request);
        JSONObject data = null;
        if ("FAILURE".equals(response.getState())) {
            if (response.getError() != null)
                data.put("code", response.getError().getCode());
            data.put("message", response.getError().getMessage());
        }
        if (response.getStringResult() != null) {
            Object object = JsonUtil.fromJson(response.getStringResult().toString(), Object.class);
            JSON json = (JSON) JSON.toJSON(object);
            data = JSONObject.parseObject(json.toJSONString());
        }
        return data;
    }

    /**
     * 调用支付api
     *
     * @param result 创建订单结果
     * @throws IOException
     */
    public static CashierdeskResult getPayUrl(YibaoorderResult result, Userwechat userwechat, String ip) throws IOException {
        YopRequest request = new YopRequest("OPR:" + ParentMerchantNo, PRIVATEKEY);
        //订单 token
        request.addParam(Common.TOKEN, result.getToken());
        //支付工具
        request.addParam("payTool", "MINI_PROGRAM");
        //支付类型
        request.addParam("payType", "WECHAT");
        //用户标识
        request.addParam("userNo", userwechat.getUnionid());
        //用户标识类型
        request.addParam("userType", "USER_ID");
        //微信的appid
        request.addParam("appId", WechatUtil.mini_appid);
        //微信用户openid
        request.addParam("openId", userwechat.getOpenid());
        //用户真实的ip地址
        request.addParam("userIp", ip);
        //版本
        request.addParam("version", "1.0");
        YopResponse response = YopRsaClient.post("/rest/v1.0/nccashierapi/api/pay", request);
        CashierdeskResult cashierdeskResult = null;
        if ("FAILURE".equals(response.getState())) {
            cashierdeskResult = new CashierdeskResult();
            cashierdeskResult.setCode(response.getError().getCode());
            cashierdeskResult.setMessage(response.getError().getMessage());
        }
        if (response.getStringResult() != null) {
            Object object = JsonUtil.fromJson(response.getResult().toString(), Object.class);
            JSON json = (JSON) JSON.toJSON(object);
            cashierdeskResult = JSONObject.toJavaObject(json, CashierdeskResult.class);
        }
        return cashierdeskResult;
    }

    /**
     * 易宝退款工具
     *
     * @throws IOException
     */
    public static Refundresult yibaoRefund(Yibaodivide yibaodivide, Userorder userorder, Yibaopayment yibaopayment) throws IOException {
        DecimalFormat amount = new DecimalFormat("0.00");
        Map<String, String> parms = new HashMap<>();
        parms.put("parentMerchantNo", ParentMerchantNo);
        parms.put("merchantNo", MerchantNo);
        //商户交易请求号
        parms.put("orderId", yibaodivide.getOrderId());
        //退款请求号
        String refundOrderNo = "4" + new Date().getTime() + userorder.getId().toString();
        parms.put("refundRequestId", refundOrderNo);
        //易宝内部生成唯一订单流水号
        parms.put("uniqueOrderNo", yibaodivide.getUniqueOrderNo());
        //退款金额
        parms.put("refundAmount", amount.format(userorder.getPayableAmount()));
        YopRequest request = new YopRequest("OPR:" + ParentMerchantNo, PRIVATEKEY);
        request.addParam("parentMerchantNo", ParentMerchantNo);
        request.addParam("merchantNo", MerchantNo);
        //商户交易请求号
        request.addParam("orderId", yibaodivide.getOrderId());
        //退款请求号
        request.addParam("refundRequestId", refundOrderNo);
        //易宝内部生成唯一订单流水号
        request.addParam("uniqueOrderNo", yibaodivide.getUniqueOrderNo());
        //退款金额
        request.addParam("refundAmount", amount.format(userorder.getPayableAmount()));
        //
        String serviceCharge = amount.format(userorder.getPayableAmount() * 0.003);
        String realAmount = amount.format(userorder.getPayableAmount() - Double.valueOf(serviceCharge));
        String accountDivided = "";
        if (Double.valueOf(serviceCharge) > 0.00) {
            accountDivided = ",{\"ledgerNo\":\"10033201678\",\"amount\":" + serviceCharge + ",\"ledgerName\":\"春悦林（广东）大药房有限公司\"}";
        }
        request.addParam("accountDivided", "[{\"ledgerNo\":\"10033160799\",\"amount\":" + realAmount + ",\"ledgerName\":\"春悦林（广东）大药房有限公司\"}" + accountDivided + "]");
        //回调通知
        request.addParam("notifyUrl", RefundNotifyUrl);
        //hmac签名
        request.addParam("hmac", HmacUtil.getrefunddevidehamc(parms));
        YopResponse response = YopRsaClient.post("/rest/v1.0/sys/trade/refund", request);
        Refundresult refundresult = null;
        if ("FAILURE".equals(response.getState())) {
            refundresult = new Refundresult();
            refundresult.setCode(response.getError().getCode());
            refundresult.setMessage(response.getError().getMessage());
        }
        if (response.getStringResult() != null) {
            Object object = JsonUtil.fromJson(response.getStringResult().toString(), Object.class);
            JSON json = (JSON) JSON.toJSON(object);
            refundresult = JSONObject.toJavaObject(json, Refundresult.class);
        }
        return refundresult;
    }

    /**
     * 易宝退款查询工具
     *
     * @throws IOException
     */
    public static JSONObject yibaoGetRefund(String orderId, String uniqueRefundNo, String refundRequestId) throws IOException {
        DecimalFormat amount = new DecimalFormat("0.00");
        Map<String, String> parms = new HashMap<>();
        parms.put("parentMerchantNo", ParentMerchantNo);
        parms.put("merchantNo", MerchantNo);
        //交易请求号
        parms.put("orderId", orderId);
        //统一退款号
        parms.put("uniqueRefundNo", uniqueRefundNo);
        //退款请求号
        parms.put("refundRequestId", refundRequestId);
        YopRequest request = new YopRequest("OPR:" + ParentMerchantNo, PRIVATEKEY);
        request.addParam("parentMerchantNo", ParentMerchantNo);
        request.addParam("merchantNo", MerchantNo);
        //交易请求号
        request.addParam("orderId", orderId);
        //退款请求号
        request.addParam("refundRequestId", uniqueRefundNo);
        //统一退款号
        request.addParam("uniqueRefundNo", refundRequestId);
        //hmac签名
        request.addParam("hmac", HmacUtil.getrefundhamc(parms));
        YopResponse response = YopRsaClient.post("/rest/v1.0/sys/trade/refundquery", request);
        JSONObject data = null;
        if ("FAILURE".equals(response.getState())) {
            if (response.getError() != null)
                data = new JSONObject();
            data.put("code", response.getError().getCode());
            data.put("message", response.getError().getMessage());
        }
        if (response.getStringResult() != null) {
            Object object = JsonUtil.fromJson(response.getStringResult().toString(), Object.class);
            JSON json = (JSON) JSON.toJSON(object);
            data = JSONObject.parseObject(json.toJSONString());
        }
        return data;
    }

    /**
     * 易宝分账工具
     *
     * @param yibaopayment
     * @throws IOException
     */
    public static Divideresult yibaoDivide(Yibaopayment yibaopayment, Userorder userorder) throws IOException {
        DecimalFormat amount = new DecimalFormat("0.00");
        String divideRequestId = "3" + new Date().getTime() + yibaopayment.getId().toString();
        Map<String, String> parms = new HashMap<>();
        YopRequest request = new YopRequest("OPR:" + ParentMerchantNo, PRIVATEKEY);
        parms.put("parentMerchantNo", ParentMerchantNo);
        parms.put("merchantNo", MerchantNo);
        parms.put("orderId", yibaopayment.getSerialNumber());
        parms.put("uniqueOrderNo", yibaopayment.getPaymentNo());
        parms.put("divideRequestId", divideRequestId);
        request.addParam("parentMerchantNo", ParentMerchantNo);
        request.addParam("merchantNo", MerchantNo);
        //商户交易请求号
        request.addParam("orderId", yibaopayment.getSerialNumber());
        //要分账订单的易宝流水号
        request.addParam("uniqueOrderNo", yibaopayment.getPaymentNo());
        //分账请求号
        request.addParam("divideRequestId", divideRequestId);
        //合同号
        request.addParam("contractNo", "10033160799");
        //分账明细
        Double serverCharge = Double.valueOf(amount.format(userorder.getPayableAmount() * 0.003));
        String realAmount = amount.format(userorder.getPayableAmount() - serverCharge);
        request.addParam("divideDetail", "[{\"ledgerNo\":\"10033160799\",\"amount\":" + realAmount + "}]");
        //是否解冻收单商户剩余可用金额
        request.addParam("isUnfreezeResidualAmount", "FALSE");
        //签名
        request.addParam("hmac", HmacUtil.getdevidehamc(parms));
        YopResponse response = YopRsaClient.post("/rest/v1.0/sys/trade/divide", request);
        Divideresult divideresult = null;
        if ("FAILURE".equals(response.getState())) {
            divideresult = new Divideresult();
            divideresult.setCode(response.getError().getCode());
            divideresult.setMessage(response.getError().getMessage());
        }
        if (response.getStringResult() != null) {
            Object object = JsonUtil.fromJson(response.getStringResult().toString(), Object.class);
            JSON json = (JSON) JSON.toJSON(object);
            divideresult = JSONObject.toJavaObject(json, Divideresult.class);
        }
        return divideresult;
    }

    /**
     * 易宝分账给平台工具
     *
     * @param yibaopayment
     * @throws IOException
     */
    public static Divideresult yibaoDivideToPlatform(Yibaopayment yibaopayment, Double price) throws IOException {
        DecimalFormat amount = new DecimalFormat("0.00");
        String divideRequestId = "3" + new Date().getTime() + yibaopayment.getId().toString();
        Map<String, String> parms = new HashMap<>();
        YopRequest request = new YopRequest("OPR:" + ParentMerchantNo, PRIVATEKEY);
        parms.put("parentMerchantNo", ParentMerchantNo);
        parms.put("merchantNo", MerchantNo);
        parms.put("orderId", yibaopayment.getSerialNumber());
        parms.put("uniqueOrderNo", yibaopayment.getPaymentNo());
        parms.put("divideRequestId", divideRequestId);
        request.addParam("parentMerchantNo", ParentMerchantNo);
        request.addParam("merchantNo", MerchantNo);
        //商户交易请求号
        request.addParam("orderId", yibaopayment.getSerialNumber());
        //要分账订单的易宝流水号
        request.addParam("uniqueOrderNo", yibaopayment.getPaymentNo());
        //分账请求号
        request.addParam("divideRequestId", divideRequestId);
        //合同号
        request.addParam("contractNo", "10033160799");
        //分账明细
        String money = amount.format(price);
        request.addParam("divideDetail", "[{\"ledgerNo\":\"10033160799\",\"amount\":" + money + "}]");
        //是否解冻收单商户剩余可用金额
        request.addParam("isUnfreezeResidualAmount", "FALSE");
        //签名
        request.addParam("hmac", HmacUtil.getdevidehamc(parms));
        YopResponse response = YopRsaClient.post("/rest/v1.0/sys/trade/divide", request);
        Divideresult divideresult = null;
        if ("FAILURE".equals(response.getState())) {
            divideresult = new Divideresult();
            divideresult.setCode(response.getError().getCode());
            divideresult.setMessage(response.getError().getMessage());
        }
        if (response.getStringResult() != null) {
            Object object = JsonUtil.fromJson(response.getStringResult().toString(), Object.class);
            JSON json = (JSON) JSON.toJSON(object);
            divideresult = JSONObject.toJavaObject(json, Divideresult.class);
        }
        return divideresult;
    }

    /**
     * 易宝分账给商家工具
     *
     * @param yibaopayment
     * @throws IOException
     */
    public static Divideresult yibaoDivideToMerchant(String orderId, String uniqueOrderNo, Double price, String merchantNo) throws IOException {
        DecimalFormat amount = new DecimalFormat("0.00");
        String divideRequestId = "3" + new Date().getTime() + SmsUtil.getRandom(3).toString();
        Map<String, String> parms = new HashMap<>();
        YopRequest request = new YopRequest("OPR:" + ParentMerchantNo, PRIVATEKEY);
        parms.put("parentMerchantNo", ParentMerchantNo);
        parms.put("merchantNo", MerchantNo);
        parms.put("orderId", orderId);
        parms.put("uniqueOrderNo", uniqueOrderNo);
        parms.put("divideRequestId", divideRequestId);
        request.addParam("parentMerchantNo", ParentMerchantNo);
        request.addParam("merchantNo", MerchantNo);
        //商户交易请求号
        request.addParam("orderId", orderId);
        //要分账订单的易宝流水号
        request.addParam("uniqueOrderNo", uniqueOrderNo);
        //分账请求号
        request.addParam("divideRequestId", divideRequestId);
        //合同号
        request.addParam("contractNo", "10033160799");
        //分账明细
        String money = amount.format(price);
        request.addParam("divideDetail", "[{\"ledgerNo\":" + merchantNo + ",\"amount\":" + money + "}]");
        //是否解冻收单商户剩余可用金额
        request.addParam("isUnfreezeResidualAmount", "FALSE");
        //签名
        request.addParam("hmac", HmacUtil.getdevidehamc(parms));
        YopResponse response = YopRsaClient.post("/rest/v1.0/sys/trade/divide", request);
        Divideresult divideresult = null;
        if ("FAILURE".equals(response.getState())) {
            divideresult = new Divideresult();
            divideresult.setCode(response.getError().getCode());
            divideresult.setMessage(response.getError().getMessage());
        }
        if (response.getStringResult() != null) {
            Object object = JsonUtil.fromJson(response.getStringResult().toString(), Object.class);
            JSON json = (JSON) JSON.toJSON(object);
            divideresult = JSONObject.toJavaObject(json, Divideresult.class);
        }
        return divideresult;
    }

    /**
     * 易宝分账工具
     *
     * @param yibaopayment
     * @throws IOException
     */
    public static Divideresult testyibaoDivide(String orderId, String uniqueOrderNo, Double price) throws IOException {
        DecimalFormat amount = new DecimalFormat("0.00");
        String divideRequestId = "3" + new Date().getTime() + SmsUtil.getRandom(3).toString();
        Map<String, String> parms = new HashMap<>();
        YopRequest request = new YopRequest("OPR:" + ParentMerchantNo, PRIVATEKEY);
        parms.put("parentMerchantNo", ParentMerchantNo);
        parms.put("merchantNo", MerchantNo);
        parms.put("orderId", orderId);
        parms.put("uniqueOrderNo", uniqueOrderNo);
        parms.put("divideRequestId", divideRequestId);
        request.addParam("parentMerchantNo", ParentMerchantNo);
        request.addParam("merchantNo", MerchantNo);
        //商户交易请求号
        request.addParam("orderId", orderId);
        //要分账订单的易宝流水号
        request.addParam("uniqueOrderNo", uniqueOrderNo);
        //分账请求号
        request.addParam("divideRequestId", divideRequestId);
        //合同号
        request.addParam("contractNo", "10033160799");
        //分账明细
        String money = amount.format(price);
        request.addParam("divideDetail", "[{\"ledgerNo\":\"10033160799\",\"amount\":" + money + "}]");
        //是否解冻收单商户剩余可用金额
        request.addParam("isUnfreezeResidualAmount", "FALSE");
        //签名
        request.addParam("hmac", HmacUtil.getdevidehamc(parms));
        YopResponse response = YopRsaClient.post("/rest/v1.0/sys/trade/divide", request);
        Divideresult divideresult = null;
        if ("FAILURE".equals(response.getState())) {
            divideresult = new Divideresult();
            divideresult.setCode(response.getError().getCode());
            divideresult.setMessage(response.getError().getMessage());
        }
        if (response.getStringResult() != null) {
            Object object = JsonUtil.fromJson(response.getStringResult().toString(), Object.class);
            JSON json = (JSON) JSON.toJSON(object);
            divideresult = JSONObject.toJavaObject(json, Divideresult.class);
        }
        return divideresult;
    }

    /**
     * 易宝分账查询工具
     *
     * @param orderId
     * @param uniqueOrderNo
     * @param divideRequestId
     * @return
     * @throws IOException
     */
    public static JSONObject getYibaoDivide(String orderId, String uniqueOrderNo, String divideRequestId) throws IOException {
        DecimalFormat amount = new DecimalFormat("0.00");
        Map<String, String> parms = new HashMap<>();
        YopRequest request = new YopRequest("OPR:" + ParentMerchantNo, PRIVATEKEY);
        parms.put("parentMerchantNo", ParentMerchantNo);
        parms.put("merchantNo", MerchantNo);
        parms.put("orderId", orderId);
        parms.put("uniqueOrderNo", uniqueOrderNo);
        parms.put("divideRequestId", divideRequestId);
        request.addParam("parentMerchantNo", ParentMerchantNo);
        request.addParam("merchantNo", MerchantNo);
        //商户交易请求号
        request.addParam("orderId", orderId);
        //要分账订单的易宝流水号
        request.addParam("uniqueOrderNo", uniqueOrderNo);
        //分账请求号
        request.addParam("divideRequestId", divideRequestId);
        //合同号
//			request.addParam("contractNo", "10033160799");
        //签名
        request.addParam("hmac", HmacUtil.getdevidehamc(parms));
        YopResponse response = YopRsaClient.post("/rest/v1.0/sys/trade/dividequery", request);
        JSONObject data = null;
        if ("FAILURE".equals(response.getState())) {
            if (response.getError() != null)
                data = new JSONObject();
            data.put("code", response.getError().getCode());
            data.put("message", response.getError().getMessage());
        }
        if (response.getStringResult() != null) {
            Object object = JsonUtil.fromJson(response.getStringResult().toString(), Object.class);
            JSON json = (JSON) JSON.toJSON(object);
            data = JSONObject.parseObject(json.toJSONString());
        }
        return data;
    }

    /**
     * 手动易宝分账查询工具
     *
     * @param yibaopayment
     * @throws IOException
     */
    public static JSONObject testGetYibaoDivide(String orderId, String uniqueOrderNo, String divideRequestId) throws IOException {
        DecimalFormat amount = new DecimalFormat("0.00");
        Map<String, String> parms = new HashMap<>();
        YopRequest request = new YopRequest("OPR:" + ParentMerchantNo, PRIVATEKEY);
        parms.put("parentMerchantNo", ParentMerchantNo);
        parms.put("merchantNo", MerchantNo);
        parms.put("orderId", orderId);
        parms.put("uniqueOrderNo", uniqueOrderNo);
        parms.put("divideRequestId", divideRequestId);
        request.addParam("parentMerchantNo", ParentMerchantNo);
        request.addParam("merchantNo", MerchantNo);
        //商户交易请求号
        request.addParam("orderId", orderId);
        //要分账订单的易宝流水号
        request.addParam("uniqueOrderNo", uniqueOrderNo);
        //分账请求号
        request.addParam("divideRequestId", divideRequestId);
        //合同号
//			request.addParam("contractNo", "10033160799");
        //签名
        request.addParam("hmac", HmacUtil.getdevidehamc(parms));
        YopResponse response = YopRsaClient.post("/rest/v1.0/sys/trade/dividequery", request);
        JSONObject data = null;
        if ("FAILURE".equals(response.getState())) {
            if (response.getError() != null)
                data = new JSONObject();
            data.put("code", response.getError().getCode());
            data.put("message", response.getError().getMessage());
        }
        if (response.getStringResult() != null) {
            Object object = JsonUtil.fromJson(response.getStringResult().toString(), Object.class);
            JSON json = (JSON) JSON.toJSON(object);
            data = JSONObject.parseObject(json.toJSONString());
        }
        return data;
    }

    /**
     * 资金全额确认
     *
     * @param yibaopayment
     * @throws IOException
     */
    public static JSONObject yibaoFullsettle(Yibaopayment yibaopayment) throws IOException {
        Map<String, String> parms = new HashMap<>();
        parms.put("parentMerchantNo", ParentMerchantNo);
        parms.put("merchantNo", MerchantNo);
        parms.put("orderId", yibaopayment.getSerialNumber());
        parms.put("uniqueOrderNo", yibaopayment.getPaymentNo());
        YopRequest request = new YopRequest("OPR:" + ParentMerchantNo, PRIVATEKEY);
        request.addParam("parentMerchantNo", ParentMerchantNo);
        request.addParam("merchantNo", MerchantNo);
        //商户交易请求号
        request.addParam("orderId", yibaopayment.getSerialNumber());
        //要分账订单的易宝流水号
        request.addParam("uniqueOrderNo", yibaopayment.getPaymentNo());
        //签名
        request.addParam("hmac", HmacUtil.getfullsettlehamc(parms));
        YopResponse response = YopRsaClient.post("/rest/v1.0/sys/trade/fullsettle", request);
        JSONObject data = null;
        if ("FAILURE".equals(response.getState())) {
            if (response.getError() != null)
                data = new JSONObject();
            data.put("code", response.getError().getCode());
            data.put("message", response.getError().getMessage());
        }
        if (response.getStringResult() != null) {
            Object object = JsonUtil.fromJson(response.getStringResult().toString(), Object.class);
            JSON json = (JSON) JSON.toJSON(object);
            data = JSONObject.parseObject(json.toJSONString());
        }
        return data;

    }

    /**
     * 易宝退款工具
     *
     * @throws IOException
     */
    public static Refundresult testyibaoRefund(String orderId, String uniqueOrderNo, Double price) throws IOException {
        DecimalFormat amount = new DecimalFormat("0.00");
        Map<String, String> parms = new HashMap<>();
        parms.put("parentMerchantNo", ParentMerchantNo);
        parms.put("merchantNo", MerchantNo);
        //商户交易请求号
        parms.put("orderId", orderId);
        //退款请求号
        String refundOrderNo = "4" + new Date().getTime() + SmsUtil.getRandom(3).toString();
        parms.put("refundRequestId", refundOrderNo);
        //易宝内部生成唯一订单流水号
        parms.put("uniqueOrderNo", uniqueOrderNo);
        //退款金额
        parms.put("refundAmount", amount.format(price));
        YopRequest request = new YopRequest("OPR:" + ParentMerchantNo, PRIVATEKEY);
        request.addParam("parentMerchantNo", ParentMerchantNo);
        request.addParam("merchantNo", MerchantNo);
        //商户交易请求号
        request.addParam("orderId", orderId);
        //退款请求号
        request.addParam("refundRequestId", refundOrderNo);
        //易宝内部生成唯一订单流水号
        request.addParam("uniqueOrderNo", uniqueOrderNo);
        //退款金额
        request.addParam("refundAmount", amount.format(price));
        //
        request.addParam("accountDivided", "[{\"ledgerNo\":\"10033160799\",\"amount\":" + amount.format(price) + ",\"ledgerName\":\"春悦林（广东）大药房有限公司\"}]");
        //回调通知
        request.addParam("notifyUrl", RefundNotifyUrl);
        //hmac签名
        request.addParam("hmac", HmacUtil.getrefunddevidehamc(parms));
        YopResponse response = YopRsaClient.post("/rest/v1.0/sys/trade/refund", request);
        Refundresult refundresult = null;
        if ("FAILURE".equals(response.getState())) {
            refundresult = new Refundresult();
            refundresult.setCode(response.getError().getCode());
            refundresult.setMessage(response.getError().getMessage());
        }
        if (response.getStringResult() != null) {
            Object object = JsonUtil.fromJson(response.getStringResult().toString(), Object.class);
            JSON json = (JSON) JSON.toJSON(object);
            refundresult = JSONObject.toJavaObject(json, Refundresult.class);
        }
        return refundresult;
    }

    /**
     * 查询支行信息
     *
     * @param headBankCode
     * @param provinceCode
     * @param cityCode
     * @return
     * @throws Exception
     */
    public static Map<String, Object> yibaoGetBranch(String headBankCode, String provinceCode, String cityCode) throws Exception {
        YopRequest request = new YopRequest("OPR:" + ParentMerchantNo, PRIVATEKEY);
        request.addParam("parentMerchantNo", ParentMerchantNo);
        request.addParam("headBankCode", headBankCode);
        request.addParam("provinceCode", provinceCode);
        request.addParam("cityCode", cityCode);
        YopResponse response = YopRsaClient.post("/rest/v1.0/sys/merchant/bankbranchinfo", request);
        Map<String, Object> params = null;
        if ("FAILURE".equals(response.getState())) {
            if (response.getError() != null)
                params = new HashMap<String, Object>();
            params.put("returnMsg", response.getError().getMessage());
            params.put("returnCode", response.getError().getCode());
        }
        if (response.getStringResult() != null) {
            Branchbank branchbank = JsonUtil.fromJson(response.getStringResult().toString(), Branchbank.class);
            params = branchbank.getBranchBankInfo();
        }
        return params;
    }

    /**
     * 易宝查询商家入驻状态
     *
     * @param merchantNo
     * @return
     * @throws IOException
     */
    public static JSONObject getMerchantEnterYibao(String merchantNo) throws IOException {
        YopRequest request = new YopRequest("OPR:" + ParentMerchantNo, PRIVATEKEY);
        request.addParam("parentMerchantNo", ParentMerchantNo);
        request.addParam("merchantNo", merchantNo);
        YopResponse response = YopRsaClient.post("/rest/v1.0/sys/merchant/regstatusquery", request);
        JSONObject data = null;
        if ("FAILURE".equals(response.getState())) {
            if (response.getError() != null)
                data = new JSONObject();
            data.put("code", response.getError().getCode());
            data.put("message", response.getError().getMessage());
        }
        if (response.getStringResult() != null) {
            Object object = JsonUtil.fromJson(response.getStringResult().toString(), Object.class);
            JSON json = (JSON) JSON.toJSON(object);
            data = JSONObject.parseObject(json.toJSONString());
        }
        return data;
    }

    /**
     * Map转String
     *
     * @param map
     * @return
     */
    public static String getMapToString(Map<String, Object> map) {
        Set<String> keySet = map.keySet();
        //将set集合转换为数组
        String[] keyArray = keySet.toArray(new String[keySet.size()]);
        //给数组排序(升序)
        Arrays.sort(keyArray);
        //因为String拼接效率会很低的，所以转用StringBuilder
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < keyArray.length; i++) {
            // 参数值为空，则不参与签名 这个方法trim()是去空格
            if ((String.valueOf(map.get(keyArray[i]))).trim().length() > 0) {
                sb.append(keyArray[i]).append(":").append(String.valueOf(map.get(keyArray[i])).trim());
            }
            if (i != keyArray.length - 1) {
                sb.append(",");
            }
        }
        return sb.toString();
    }

    /**
     * 易宝上传文件
     *
     * @param pathUrl
     * @return
     * @throws MalformedURLException
     * @throws IOException
     */
    public static String yibaoUploadFile(String pathUrl) throws MalformedURLException, IOException {
        String uri = "/yos/v1.0/sys/merchant/qual/upload";
        YopRequest request = new YopRequest("OPR:" + ParentMerchantNo, PRIVATEKEY);
        //指定文件URL
        request.addFile("merQual", new URL(pathUrl).openStream());
        YopResponse response = YopRsaClient.upload(uri, request);
        JSONObject data = null;
        if (response.getStringResult() != null) {
            Object object = JsonUtil.fromJson(response.getStringResult().toString(), Object.class);
            JSON json = (JSON) JSON.toJSON(object);
            data = JSONObject.parseObject(json.toJSONString());
        }
        return data.getString("merQualUrl");
    }

    /**
     * 易宝回调工具
     *
     * @param response
     * @return
     */
    public static String callBack(String response) {
        DigitalEnvelopeDTO dto = new DigitalEnvelopeDTO();
        dto.setCipherText(response);
        try {
            //设置商户私钥
            PrivateKey privateKey = getPrivateKey();
            ;
            //设置易宝公钥
            PublicKey publicKey = getPubKey();
            //解密验签
            dto = DigitalEnvelopeUtils.decrypt(dto, privateKey, publicKey);
            //打印回调数据
            return dto.getPlainText();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 实例化公钥
     *
     * @return
     */
    private static PublicKey getPubKey() {
        PublicKey publicKey = null;
        // RSA对称加密算法
        try {
            X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(new BASE64Decoder().decodeBuffer(PUBLICKEY));
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            publicKey = keyFactory.generatePublic(bobPubKeySpec);
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return publicKey;
    }

    /**
     * 实例化密钥
     *
     * @return
     */
    private static PrivateKey getPrivateKey() {
        PrivateKey privateKey = null;
        try {
            PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(new BASE64Decoder().decodeBuffer(PRIVATEKEY));
            KeyFactory keyf = KeyFactory.getInstance("RSA");
            privateKey = keyf.generatePrivate(priPKCS8);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return privateKey;
    }


    public static void main(String[] args) throws Exception {
        //JSONObject data = getMerchantEnterYibao("10033344042");
        //System.out.println(data.toJSONString());
        //Divideresult divideresult = testyibaoDivide("0157780811409028188", "1001202001010000001384729260", 999.00);
        //System.out.println(divideresult.toString());
        JSONObject data = testGetYibaoDivide("00001631579188254958", "1001202001160000001415223554", "315791883767944952");
        System.out.println(data.toJSONString());
    }
}
